package com.tcs.teg.utils.common;

import java.io.Serializable;
import java.sql.Timestamp;
import java.util.Date;

import org.hibernate.EmptyInterceptor;
import org.hibernate.Transaction;
import org.hibernate.type.Type;

public class BasicEntityInterceptor extends EmptyInterceptor {

    /**
	 * 
	 */
	private static final long serialVersionUID = 1L;
	
    @Override
    public void onDelete(Object entity,
                         Serializable id,
                         Object[] state,
                         String[] propertyNames,
                         Type[] types) {
        // do nothing
    }
    
    @Override
    public boolean onFlushDirty(Object entity,
                                Serializable id,
                                Object[] currentState,
                                Object[] previousState,
                                String[] propertyNames,
                                Type[] types) {
    	//logger.debug("=================================================================================");
    	//logger.debug("-----------BasicEntityInterceptor----onFlushDirty-----");
    	//logger.debug("=================================================================================");
    	return false;
        /*if ( entity instanceof DocumentType ) {           
            DocumentType dt = null;            
            for ( Object o : currentState ) {             	
            	if (o instanceof DocumentType){
            		dt = (DocumentType) o;
            		dt.setUpdateDateTime(new Timestamp(new Date().getTime()));
            		dt.setInsertDateTime(new Timestamp(new Date().getTime()));
            	}
            }
        }*/            
       
    }
    
    @Override
    public boolean onLoad(Object entity,
                          Serializable id,
                          Object[] state,
                          String[] propertyNames,
                          Type[] types) {
        return false;
    }
    //@Override
    public boolean onSave(Object entity,
                          Serializable id,
                          Object[] state,
                          String[] propertyNames,
                          Type[] types) {
    	//logger.debug("=================================================================================");
    	//logger.debug("----------------------------------------------------------------onSave----------");
    	//logger.debug("=================================================================================");
    	
        	
            /**
             * So what did we do? First, we implemented the onFlushDirty and onSave methods because they are called for SQL updates and inserts, respectively. 
             * For example, when a new entity is first saved, the onSave method is called, at which point we want to set the createdBy and properties. 
             * And if an existing entity is updated, onFlushDirty is called and we set the updatedBy and updatedOn.
             * 
             * 
             * Second, we are using the setValue helper method to do the real work. Specfically, the only way to modify the state in a 
             * Hibernate Interceptor (that I am aware of anyway) is to dig into the currentState array and change the appropriate value. 
             * In order to do that, you first need to trawl through the propertyNames array to find the index of the property you are trying to set. 
             * For example, if you are updating a blog entry you need to set the updatedBy and updatedOn properties within the currentState array. 
             * For a BlogEntry object, the currentState array might look like this before the update (the updated by and on 
             * propertes are both null in this case because the entity was created by Bob but has not been updated yet):
             * 
             */
        	
        	setValue(state, propertyNames, "insertUser","TESTUSER");
        	setValue(state, propertyNames, "insertDateTime",new Timestamp(new Date().getTime()));
        	setValue(state, propertyNames, "insertUserNamespace","TESTUSER");
        	setValue(state, propertyNames, "updateUserNamespace","TESTUSER");
        	setValue(state, propertyNames, "updateDateTime",new Timestamp(new Date().getTime()));
        	setValue(state, propertyNames, "updateUser","TESTUSER");
			return true;//super.onSave(entity, id, state, propertyNames, types);
    }

    
    
    @Override
    public void afterTransactionCompletion(Transaction tx) {
    	
    }
    
    /**
     * So what did we do? First, we implemented the onFlushDirty and onSave methods because they are called for SQL updates and inserts, respectively. 
     * For example, when a new entity is first saved, the onSave method is called, at which point we want to set the createdBy and properties. 
     * And if an existing entity is updated, onFlushDirty is called and we set the updatedBy and updatedOn.
     * 
     * 
     * Second, we are using the setValue helper method to do the real work. Specfically, the only way to modify the state in a 
     * Hibernate Interceptor (that I am aware of anyway) is to dig into the currentState array and change the appropriate value. 
     * In order to do that, you first need to trawl through the propertyNames array to find the index of the property you are trying to set. 
     * For example, if you are updating a blog entry you need to set the updatedBy and updatedOn properties within the currentState array. 
     * For a BlogEntry object, the currentState array might look like this before the update (the updated by and on 
     * propertes are both null in this case because the entity was created by Bob but has not been updated yet):
     * 
     */
    private void setValue(Object[] currentState, String[] propertyNames,
    		String propertyToSet, Object value) 
    {		int i = 0;
    		for(String propertyName: propertyNames){    			
    			if(propertyName.equalsIgnoreCase(propertyToSet)){
    				currentState[i]=value;
    			}
    			i++;
    		}
	}

}
